#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

//函数指针类型
typedef void(*fun_t)();

#define NUM 5
fun_t handlers[NUM + 1];

//任务
void DownLoad()
{
    printf("这是一个下载任务...\n");
}

void Flush()
{
    printf("这是一个刷新任务...\n");
}

void Log()
{
    printf("这是一个记录日志...\n");
}


//注册
void registerHandler(fun_t h[],fun_t f)
{
    int i = 0;
    for(;i < NUM;i++)
    {
        if(h[i] == NULL)
        {
            break;
        }
    }
    if(i == NUM)
    {
        return;
    }
    h[i] = f;
    h[i + 1] = NULL;
}


int main()
{
    registerHandler(handlers,DownLoad);
    registerHandler(handlers,Flush);
    registerHandler(handlers,Log);

    pid_t id = fork();
    if(id == 0)
    {
        int cnt = 5;
        while(1)
        {
            sleep(1);
            printf("子进程执行->%d  父进程是->%d\n", getpid(),getppid());
        }
        //sleep(2);
        //int* pi = 0;
        //*pi = 1;
        //int a = 10;
        //a /= 0;
        exit(10);
    }
    sleep(2);
    
    //父进程
    while(1)
    {
        int status = 0;
        //非阻塞等待
        pid_t rid = waitpid(id, &status, WNOHANG);
        if(rid > 0)
        {
            //等待成功
            printf("进程成功回收->%d 进程的退出码是->%d 进程的退出信号为->%d\n", rid, WEXITSTATUS(status),status & 0x7F);
            break;
        }
        else if(rid == 0)
        {
            //等待运行
            //函数指针进行回调
            int i = 0;
            for(;handlers[i];i++)
            {
                handlers[i]();
            }
            printf("本轮调用结束，子进程没有退出...\n");
            sleep(1);
        }
        else
        {
            printf("等待失败\n");
            break;
        }
    }

    ////pid_t rid = wait(NULL);
    //int status = 0;
    //pid_t rid = waitpid(id,&status,0);
    //if(rid > 0)
    //{
    //    //printf("进程成功回收->%d 进程的退出码是->%d 进程的退出信号为->%d\n", rid, (status >> 8) & 0xFF,status & 0x7F);
    //    if(WIFEXITED(status))
    //    {
    //         printf("进程成功回收->%d 进程的退出码是->%d 进程的退出信号为->%d\n", rid, WEXITSTATUS(status),status & 0x7F);
    //    }
    //    else
    //    {
    //        printf("进程退出异常\n");
    //    }
    //}
    //else
    //{
    //    printf("进程错误回收->%d, %s\n", errno, strerror(errno));
    //}
   // while(1)
   // {
   //     sleep(1);
   // }
    return 0;
}

//void fun()
//{
//    printf("fun() begin\n");
//    //exit(1);
//    _exit(1);
//    printf("fun() end\n");
//}
//
//int main()
//{
//
//    //printf("hello world!");
//    //sleep(2);
//    ////exit是C的库函数，实现了清除缓冲区的功能，而系统函数_exit没有实现该功能
//    //_exit(1);
//
//    //exit(1);
//
//    //fun();
//
//    //FILE* fp = fopen("hello.txt","r");
//    //if(fp == NULL)
//    //{
//    //    return 2;
//    //}
//
//
//    //for(int i = 0;i < 200;i++)
//    //{
//    //    printf("%d->%s\n", i,strerror(i));
//    //}
//
//
//    //echo $? 查看最近进程的退出码
//    //printf("hello mihayou\n");
//    //return 2;
//
//    return 0;
//}
